home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / ck5a189s / ckuus7.c < prev    next >
C/C++ Source or Header  |  1993-06-15  |  63KB  |  2,216 lines

  1. #ifndef NOICP
  2.  
  3. /*  C K U U S 7 --  "User Interface" for Unix Kermit, part 7  */
  4.  
  5. /*
  6.   Author: Frank da Cruz (fdc@columbia.edu, FDCCU@CUVMA.BITNET),
  7.   Columbia University Academic Information Systems, New York City.
  8.  
  9.   Copyright (C) 1985, 1993, Trustees of Columbia University in the City of New
  10.   York.  The C-Kermit software may not be, in whole or in part, licensed or
  11.   sold for profit as a software product itself, nor may it be included in or
  12.   distributed with commercial products or otherwise distributed by commercial
  13.   concerns to their clients or customers without written permission of the
  14.   Office of Kermit Development and Distribution, Columbia University.  This
  15.   copyright notice must not be removed, altered, or obscured.
  16. */
  17.  
  18. /*
  19.   This file created from parts of ckuus3.c, which became to big for
  20.   Mark Williams Coherent compiler to handle.
  21. */
  22.  
  23. /*
  24.   Definitions here supersede those from system include files.
  25. */
  26. #include "ckcdeb.h"            /* Debugging & compiler things */
  27. #include "ckcasc.h"            /* ASCII character symbols */
  28. #include "ckcker.h"            /* Kermit application definitions */
  29. #include "ckcxla.h"            /* Character set translation */
  30. #include "ckcnet.h"            /* Network symbols */
  31. #include "ckuusr.h"            /* User interface symbols */
  32.  
  33. static int x, y = 0, z;
  34. static char *s;
  35.  
  36. #ifdef CK_SPEED
  37. extern short ctlp[];            /* Control-char prefixing table */
  38. #endif /* CK_SPEED */
  39.  
  40. static int mdmsav = -1;            /* Save modem type around network */
  41. static int oldplex = -1;        /* Duplex holder around network */
  42.  
  43. extern int success, nfilp, fmask, fncnv, frecl, nfttyp, binary, warn, msgflg;
  44. extern int cmask, maxrps, wslotr, bigsbsiz, bigrbsiz, urpsiz, rpsiz, spsiz;
  45. extern int spsizr, spsizf, maxsps, spmax, pflag, bctr, npad, timef, timint;
  46. extern int pkttim, rtimo, local, nfils, displa, atcapr, nettype, escape;
  47. extern int mdmtyp, duplex, dfloc, network, cdtimo, fncact, mypadn;
  48. extern int tnlm, sosi, tlevel, lf_opts, backgrd, flow, fdispla;
  49. extern int
  50.   atenci, atenco, atdati, atdato, atleni, atleno, atblki, atblko,
  51.   attypi, attypo, atsidi, atsido, atsysi, atsyso, atdisi, atdiso; 
  52.  
  53. extern long speed;
  54.  
  55. extern CHAR sstate, eol, seol, stchr, mystch, mypadc, padch, ctlq, myctlq;
  56.  
  57. extern char *cmarg, *cmarg2, *dftty;
  58.  
  59. extern char *tp, *lp;            /* Temporary buffer & pointers */
  60. #ifndef NOFRILLS
  61. extern char optbuf[];            /* Buffer for MAIL or PRINT options */
  62. extern int rprintf;            /* REMOTE PRINT flag */
  63. #endif /* NOFRILLS */
  64. extern char ttname[];
  65.  
  66. extern struct keytab onoff[], filtab[], fttab[], rltab[];
  67. extern int nrlt;
  68.  
  69. #ifdef DCMDBUF
  70. extern char *atxbuf;            /* Atom buffer */
  71. extern char *cmdbuf;            /* Command buffer */
  72. extern char *line, *tmpbuf;        /* Character buffers for anything */
  73. extern int *intime;            /* INPUT TIMEOUT */
  74. #ifdef CK_CURSES
  75. /* This needs cleaning up... */
  76. #ifdef UNIX
  77. extern char *trmbuf;            /* Termcap buffer */
  78. #endif /* UNIX */
  79. #ifdef OS2
  80. extern char *trmbuf;            /* Termcap buffer */
  81. #endif /* OS2 */
  82. #ifdef OSK
  83. extern char *trmbuf;            /* Termcap buffer */
  84. #endif /* OSK */
  85. #ifdef AMIGA
  86. extern char *trmbuf;            /* Termcap buffer */
  87. #endif /* AMIGA */
  88. #endif /* CK_CURSES */
  89. #else
  90. extern char atxbuf[];            /* Atom buffer */
  91. extern char cmdbuf[];            /* Command buffer */
  92. extern char line[], tmpbuf[];        /* Character buffer for anything */
  93. extern int intime[];
  94. #ifdef CK_CURSES
  95. #ifdef UNIX
  96. extern char trmbuf[];            /* Termcap buffer */
  97. #endif /* UNIX */
  98. #endif /* CK_CURSES */
  99. #endif /* DCMDBUF */
  100.  
  101. #ifndef NOCSETS
  102. extern struct keytab fcstab[];        /* For 'set file character-set' */
  103. extern struct keytab ttcstab[];
  104. extern int nfilc, fcharset, ntermc, tcsr, tcsl;
  105. #endif /* NOCSETS */
  106.  
  107. #ifndef NOSPL
  108. extern int cmdlvl;            /* Overall command level */
  109. #ifdef DCMDBUF
  110. extern int *inpcas;            /* INPUT CASE setting on cmd stack */
  111. #else
  112. extern int inpcas[];
  113. #endif /* DCMDBUF */
  114. #endif /* NOSPL */
  115.  
  116. #ifdef TNCODE
  117. extern int tn_init;
  118. #endif /* TNCODE */
  119.  
  120. #ifdef SUNX25
  121. extern int revcall, closgr, cudata, nx25, npadx3;
  122. extern char udata[MAXCUDATA];
  123. extern CHAR padparms[MAXPADPARMS+1];
  124. extern struct keytab x25tab[], padx3tab[];
  125. #endif /* SUNX25 */
  126.  
  127. #ifdef CK_CURSES
  128. #ifndef VMS
  129. _PROTOTYP(int tgetent,(char *, char *));
  130. #endif /* VMS */
  131. #endif /* CK_CURSES */
  132.  
  133. #ifndef NODIAL
  134. extern int dialhng, dialtmo, dialksp, dialdpy, dialmnp, dialmhu;
  135. extern int mdmspd;
  136. extern char *dialini, *dialdir, *dialcmd, *dialnpr;
  137. extern FILE * dialfd;
  138.  
  139.  
  140. struct keytab dialtab[] = {
  141.     "dial-command", XYDDIA, 0,
  142.     "directory", XYDDIR, 0,
  143.     "display", XYDDPY, 0,
  144.     "hangup",  XYDHUP, 0,
  145.     "init-string", XYDINI, 0,
  146.     "kermit-spoof", XYDKSP, 0,
  147.     "mnp-enable", XYDMNP, 0,
  148. #ifdef MDMHUP
  149.     "modem-hangup", XYDMHU, 0,
  150. #endif /* MDMHUP */
  151.     "prefix", XYDNPR, 0,
  152.     "speed-matching", XYDSPD, 0,
  153.     "timeout", XYDTMO, 0
  154. };
  155. int ndial = (sizeof(dialtab) / sizeof(struct keytab));
  156. #endif /* NODIAL */
  157.  
  158. #ifndef NOXMIT
  159. /* set transmit */
  160. #define XMITF 0
  161. #define XMITL 1
  162. #define XMITP 2
  163. #define XMITE 3
  164. #define XMITX 4
  165. #define XMITS 5
  166. #define XMITW 6
  167.  
  168. #ifndef NOXMIT
  169. #define XMBUFL 50
  170. extern int xmitf, xmitl, xmitp, xmitx, xmits, xmitw;
  171. char xmitbuf[XMBUFL+1] = { NUL };    /* TRANSMIT eof string */
  172. #endif /* NOXMIT */
  173.  
  174. struct keytab xmitab[] = {
  175.     "echo",     XMITX, 0,
  176.     "eof",      XMITE, 0,
  177.     "fill",     XMITF, 0,
  178.     "linefeed", XMITL, 0,
  179.     "locking-shift", XMITS, 0,
  180.     "pause",    XMITW, 0,
  181.     "prompt",   XMITP, 0
  182. };
  183. int nxmit = (sizeof(xmitab) / sizeof(struct keytab));
  184. #endif /* NOXMIT */
  185.  
  186. /* For SET FILE COLLISION */
  187. /* Some of the following may be possible for some C-Kermit implementations */
  188. /* but not others.  Those that are not possible for your implementation */
  189. /* should be ifdef'd out. */
  190.  
  191. struct keytab colxtab[] = { /* SET FILE COLLISION options */
  192.     "append",    XYFX_A, 0,  /* append to old file */
  193. #ifdef COMMENT
  194.     "ask",       XYFX_Q, 0,  /* ask what to do (not implemented) */
  195. #endif
  196.     "backup",    XYFX_B, 0,  /* rename old file */
  197.     "discard",   XYFX_D, 0,  /* don't accept new file */
  198.     "no-supersede", XYFX_D, CM_INV, /* ditto (MSK compatibility) */
  199.     "overwrite", XYFX_X, 0,  /* overwrite the old file == file warning off */
  200.     "rename",    XYFX_R, 0,  /* rename the incoming file == file warning on */
  201.     "update",    XYFX_U, 0,  /* replace if newer */
  202. };
  203. int ncolx = (sizeof(colxtab) / sizeof(struct keytab));
  204.  
  205. static struct keytab rfiltab[] = {    /* for REMOTE SET FILE */
  206.     "collision",     XYFILX, 0,
  207.     "names",         XYFILN, 0,
  208.     "record-length", XYFILR, 0,
  209.     "type",          XYFILT, 0
  210. };
  211. int nrfilp = (sizeof(rfiltab) / sizeof(struct keytab));
  212.  
  213. struct keytab fntab[] = {           /* File naming */
  214.     "converted", 1, 0,
  215.     "literal",   0, 0
  216. };
  217.  
  218. /* Terminal parameters table */
  219. struct keytab trmtab[] = {
  220. #ifdef OS2
  221.     "answerback",    XYTANS, 0,
  222.     "arrow-keys",    XYTARR, 0,
  223. #endif /* OS2 */
  224.     "bytesize",      XYTBYT, 0,
  225. #ifndef NOCSETS
  226.     "character-set", XYTCS,  0,
  227. #endif /* NOCSETS */
  228. #ifdef OS2
  229.     "color",         XYTCOL, 0,
  230. #endif /* OS2 */
  231.     "cr-display",    XYTCRD, 0,
  232. #ifdef OS2
  233.     "cursor",        XYTCUR, 0,
  234. #endif /* OS2 */
  235.     "echo",          XYTEC,  0,
  236. #ifdef OS2
  237.     "keypad-mode",   XYTKPD, 0,
  238. #endif /* OS2 */
  239.     "locking-shift", XYTSO,  0,
  240.     "newline-mode",  XYTNL,  0
  241. #ifdef OS2
  242. ,   "scrollback",    XYSCRS, 0,
  243.     "type",          XYTTYP, 0,
  244.     "wrap",          XYTWRP, 0
  245. #endif /* OS2 */
  246. };
  247. int ntrm = (sizeof(trmtab) / sizeof(struct keytab));
  248.  
  249. struct keytab crdtab[] = {        /* Carriage-return display */
  250.     "crlf",        1, 0,
  251.     "normal",      0, 0
  252. };
  253. extern int tt_crd;            /* Carriage-return display variable */
  254.  
  255. #ifdef OS2
  256. /*
  257.   OS/2 serial communication devices.
  258. */
  259. struct keytab os2devtab[] = {
  260.     "1",    1, CM_INV,            /* Invisible synonyms, like */
  261.     "2",    2, CM_INV,            /* "set port 1" */
  262.     "3",    3, CM_INV,
  263.     "4",    4, CM_INV,
  264.     "5",    5, CM_INV,
  265.     "6",    6, CM_INV,
  266.     "7",    7, CM_INV,
  267.     "8",    8, CM_INV,
  268.     "com1", 1, 0,            /* Real device names */
  269.     "com2", 2, 0,
  270.     "com3", 3, 0,
  271.     "com4", 4, 0,
  272.     "com5", 5, 0,
  273.     "com6", 6, 0,
  274.     "com7", 7, 0,
  275.     "com8", 7, 0
  276. };
  277. int nos2dev = (sizeof(os2devtab) / sizeof(struct keytab));
  278.  
  279. /*
  280.   Terminal parameters that can be set by SET commands.
  281.   Used by the ck?con.c terminal emulator code.  
  282.   For now, only use for OS/2.  Should add these for Macintosh.
  283. */
  284. int tt_arrow = 1;            /* Arrow key mode, 1 = Application */
  285. int tt_keypad = 0;            /* Keypad mode, 0 = Application */
  286. int tt_wrap = 1;            /* Autowrap, 1 = On */
  287. int tt_type = TT_VT102;            /* Terminal type, initially VT102 */
  288. int tt_cursor = 0;            /* Cursor type, 0 = Underline */
  289. int tt_answer = 0;            /* Answerback initially disabled */
  290. int tt_scrsize = 240;                   /* Scrollback buffer size */
  291. #endif /* OS2 */
  292.  
  293. #ifdef OS2
  294. struct keytab akmtab[] = {        /* Arrow key mode */
  295.     "application", 1, 0,
  296.     "cursor",      0, 0
  297. };
  298. struct keytab kpmtab[] = {        /* Keypad mode */
  299.     "application", 0, 0,
  300.     "numeric",     1, 0
  301. };
  302.  
  303. struct keytab ttycoltab[] = {        /* Items to be colored */
  304.     "help",        4, 0,        /* Help screen */
  305.     "normal",      0, 0,        /* Normal screen text */
  306.     "reverse",     1, 0,        /* Reverse video */
  307.     "status",      3, 0,        /* Status line */
  308.     "underlined",  2, 0            /* Underlined text */
  309. };
  310. int ncolors = 5;
  311.  
  312. struct keytab ttyclrtab[] = {        /* Colors */
  313.     "black",       0, 0,
  314.     "blue",        1, 0,
  315.     "brown",       6, 0,
  316.     "cyan",        3, 0,
  317.     "dgray",       8, 0,
  318.     "green",       2, 0,
  319.     "lblue",       9, 0,
  320.     "lcyan",      11, 0,
  321.     "lgray",       7, 0,
  322.     "lgreen",     10, 0,
  323.     "lmagenta",   13, 0,
  324.     "lred",       12, 0,
  325.     "magenta",     5, 0,
  326.     "red",         4, 0,
  327.     "white",      15, 0,
  328.     "yellow",     14, 0
  329. };
  330. int nclrs = 16;
  331.  
  332. struct keytab ttycurtab[] = {
  333.     "full",        2, 0,
  334.     "half",        1, 0,
  335.     "underline",   0, 0
  336. };
  337. int ncursors = 3;
  338. #endif /* OS2 */
  339.  
  340. #ifdef OS2
  341. struct keytab ttyptab[] = {
  342. #ifdef COMMENT
  343. /*
  344.   Not supported yet...
  345.   The idea is to let the console driver handle the escape sequences.
  346. */
  347.     "none",    TT_NONE,  0,
  348. #endif /* COMMENT */
  349. #ifdef OS2PM
  350.     "tek4014", TT_TEK40, 0,
  351. #endif /* OS2PM */
  352.     "vt102",   TT_VT102, 0,
  353.     "vt52",    TT_VT52,  0
  354. };
  355. int nttyp = 2;
  356. #endif /* OS2 */
  357.  
  358. /* #ifdef VMS */
  359. struct keytab fbtab[] = {        /* Binary record types for VMS */
  360.     "fixed",     XYFT_B, 0,        /* Fixed is normal for binary */
  361.     "undefined", XYFT_U, 0        /* Undefined if they ask for it */
  362. };
  363. int nfbtyp = (sizeof(fbtab) / sizeof(struct keytab));
  364. /* #endif */
  365.  
  366. #ifdef VMS
  367. struct keytab lbltab[] = {        /* Labeled File info */
  368.     "acl",         LBL_ACL, 0,
  369.     "backup-date", LBL_BCK, 0,
  370.     "name",        LBL_NAM, 0,
  371.     "owner",       LBL_OWN, 0,
  372.     "path",        LBL_PTH, 0
  373. };
  374. int nlblp = (sizeof(lbltab) / sizeof(struct keytab));
  375. #endif /* VMS */
  376.  
  377. struct keytab fdtab[] = {        /* SET FILE DISPLAY options */
  378. #ifdef MAC                /* Macintosh */
  379.     "fullscreen", XYFD_R, 0,        /* Full-screen but not curses */
  380.     "none",   XYFD_N, 0,
  381.     "off",    XYFD_N, CM_INV,
  382.     "on",     XYFD_R, CM_INV,
  383.     "quiet",  XYFD_N, CM_INV
  384.  
  385. #else                    /* Not Mac */
  386.     "crt", XYFD_S, 0,            /* CRT display */
  387. #ifdef CK_CURSES
  388. #ifdef COMMENT
  389.     "curses",     XYFD_C, CM_INV,    /* Full-screen, curses */
  390. #endif /* COMMENT */
  391.     "fullscreen", XYFD_C, 0,        /* Full-screen, whatever the method */
  392. #endif /* CK_CURSES */
  393.     "none",   XYFD_N, 0,        /* No display */
  394.     "off",    XYFD_N, CM_INV,        /* Ditto */
  395.     "on",     XYFD_R, CM_INV,        /* On = Serial */
  396.     "quiet",  XYFD_N, CM_INV,        /* No display */
  397.     "serial", XYFD_R, 0            /* Serial */
  398. #endif /* MAC */
  399. };
  400. int nfdtab = (sizeof(fdtab) / sizeof(struct keytab));
  401.  
  402. struct keytab rsrtab[] = {        /* For REMOTE SET RECEIVE */
  403.     "packet-length", XYLEN, 0,
  404.     "timeout", XYTIMO, 0
  405. };
  406. int nrsrtab = (sizeof(rsrtab) / sizeof(struct keytab));
  407.  
  408. /* Send/Receive Parameters */
  409.  
  410. struct keytab srtab[] = {
  411.     "control-prefix", XYQCTL, 0,
  412.     "end-of-packet", XYEOL, 0,
  413.     "packet-length", XYLEN, 0,
  414.     "pad-character", XYPADC, 0,
  415.     "padding", XYNPAD, 0,
  416.     "quote", XYQCTL, CM_INV,        /* = CONTROL-PREFIX */
  417.     "start-of-packet", XYMARK, 0,
  418.     "timeout", XYTIMO, 0
  419. };
  420. int nsrtab = (sizeof(srtab) / sizeof(struct keytab));
  421.  
  422. /* REMOTE SET */
  423.  
  424. struct keytab rmstab[] = {
  425.     "attributes",  XYATTR, 0,
  426.     "block-check", XYCHKT, 0,
  427.     "file",        XYFILE, 0,
  428.     "incomplete",  XYIFD,  0,
  429.     "receive",     XYRECV, 0,
  430.     "retry",       XYRETR, 0,
  431.     "server",      XYSERV, 0,
  432.     "transfer",    XYXFER, 0,
  433.     "window",      XYWIND, 0
  434. };
  435. int nrms = (sizeof(rmstab) / sizeof(struct keytab));
  436.  
  437. struct keytab attrtab[] = {
  438.     "all",           AT_XALL, 0,
  439. #ifdef COMMENT
  440.     "blocksize",     AT_BLKS, 0,    /* not used */
  441. #endif /* COMMENT */
  442. #ifndef NOCSETS
  443.     "character-set", AT_ENCO, 0,
  444. #endif /* NOCSETS */
  445.     "date",          AT_DATE, 0,
  446.     "disposition",   AT_DISP, 0,
  447.     "encoding",      AT_ENCO, CM_INV,
  448.     "length",        AT_LENK, 0,
  449.     "off",           AT_ALLN, 0,
  450.     "on",            AT_ALLY, 0,
  451. #ifdef COMMENT
  452.     "os-specific",   AT_SYSP, 0,    /* not used by UNIX or VMS */
  453. #endif /* COMMENT */
  454.     "system-id",     AT_SYSI, 0,
  455.     "type",          AT_FTYP, 0,
  456. };
  457. int natr = (sizeof(attrtab) / sizeof(struct keytab)); /* how many attributes */
  458.  
  459. #ifndef NOSPL
  460. extern int indef, inecho, insilence;
  461. struct keytab inptab [] = {        /* SET INPUT parameters */
  462.     "case",            IN_CAS, 0,
  463.     "default-timeout", IN_DEF, CM_INV,
  464.     "echo",            IN_ECH, 0,
  465.     "silence",         IN_SIL, 0,
  466.     "timeout-action",  IN_TIM, 0
  467. };
  468. int ninp = (sizeof(inptab) / sizeof(struct keytab));
  469.  
  470. struct keytab intimt[] = {        /* SET INPUT TIMEOUT parameters */
  471.     "proceed", 0, 0,            /* 0 = proceed */
  472.     "quit",    1, 0            /* 1 = quit */
  473. };
  474.  
  475. struct keytab incast[] = {        /* SET INPUT CASE parameters */
  476.     "ignore",  0, 0,            /* 0 = ignore */
  477.     "observe", 1, 0            /* 1 = observe */
  478. };
  479. #endif /* NOSPL */
  480.  
  481. /* The following routines broken out of doprm() to give compilers a break. */
  482.  
  483. /*  S E T O N  --  Parse on/off (default on), set parameter to result  */
  484.  
  485. int
  486. seton(prm) int *prm; {
  487.     int x, y;
  488.     if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
  489.     if ((x = cmcfm()) < 0) return(x);
  490.     *prm = y;
  491.     return(1);
  492. }
  493.  
  494. /*  S E T N U M  --  Set parameter to result of cmnum() parse.  */
  495. /*
  496.  Call with pointer to integer variable to be set,
  497.    x = number from cnum parse, y = return code from cmnum,
  498.    max = maximum value to accept, -1 if no maximum.
  499.  Returns -9 on failure, after printing a message, or 1 on success.
  500. */
  501. int
  502. setnum(prm,x,y,max) int x, y, *prm, max; {
  503.     extern int cmflgs;
  504.     debug(F101,"setnum","",y);
  505.     if (y == -3) {
  506.     printf("\n?Value required\n");
  507.     return(-9);
  508.     }
  509.     if (y == -2) {
  510.     printf("%s?Not a number: %s\n",cmflgs == 1 ? "" : "\n", atxbuf);
  511.     return(-9);
  512.     }
  513.     if (y < 0) return(y);
  514.     if (max > -1 && x > max) {
  515.     printf("?Sorry, %d is the maximum\n",max);
  516.     return(-9);
  517.     }
  518.     if ((y = cmcfm()) < 0) return(y);
  519.     *prm = x;
  520.     return(1);
  521. }
  522.  
  523. /*  S E T C C  --  Set parameter to an ASCII control character value.  */
  524.  
  525. int
  526. setcc(prm,x,y) int x, y, *prm; {
  527.     if (y == -3) {
  528.     printf("\n?Value required\n");
  529.     return(-3);
  530.     }
  531.     if (y < 0) return(y);
  532.     if ((x > 037) && (x != 0177)) {
  533.     printf("\n?Not in ASCII control range - %d\n",x);
  534.     return(-2);
  535.     }
  536.     if ((y = cmcfm()) < 0) return(y);
  537.     *prm = x;
  538.     return(1);
  539. }
  540.  
  541. #ifndef NODIAL
  542. _PROTOTYP(static int dialstr,(char **, char *));
  543. /*
  544.   Parse a DIAL-related string, stripping enclosing braces, if any.
  545. */
  546. static int
  547. dialstr(p,msg) char **p; char *msg; {
  548.     int x;
  549.     if ((x = cmtxt(msg, "", &s, xxstring)) < 0)
  550.       return(x);
  551.     if (*s == '{') {            /* Strip enclosing braces, if any */
  552.     x = strlen(s);
  553.     if (s[x-1] == '}') {
  554.         s[x-1] = NUL;
  555.         s++;
  556.     }
  557.     }
  558.     if (*p) {                /* Free any previous string. */
  559.     free(*p);
  560.     *p = (char *) 0;
  561.     }    
  562.     if ((x = strlen(s)) > 0) {
  563.     *p = malloc(x + 1);        /* Allocate space for it */
  564.     strcpy(*p,s);            /* and make a safe copy. */
  565.     } else *p = (char *) 0;
  566.     return(success = 1);
  567. }
  568.  
  569. int                    /* Set DIAL command options */
  570. setdial() {
  571.     if ((y = cmkey(dialtab,ndial,"","",xxstring)) < 0) return(y);
  572.     switch (y) {
  573.       case XYDHUP:            /* DIAL HANGUP */
  574.     return(success = seton(&dialhng));
  575.       case XYDINI:            /* DIAL INIT-STRING */
  576.     return(dialstr(&dialini,"Modem dialer initialization string"));
  577.       case XYDNPR:            /* DIAL NUMBER-PREFIX */
  578.     return(dialstr(&dialnpr,"Modem dialer telephone number prefix"));
  579.       case XYDDIA:            /* DIAL DIAL-COMMAND */
  580.     x = cmtxt("Dialing command for modem,\n\
  581.  include \"%s\" to stand for phone number,\n\
  582.  for example, \"set dial dial-command ATDT%s\\13\"",
  583.           "",
  584.           &s,
  585.           xxstring);
  586.     if (x < 0 && x != -3)        /* Handle parse errors */
  587.       return(x);
  588.     y = x = strlen(s);        /* Get length of text */
  589.     if (x > 0 && *s == '{') {    /* Strip enclosing braces, */
  590.         if (s[x-1] == '}') {    /* if any. */
  591.         s[x-1] = NUL;
  592.         s++;
  593.         y -= 2;
  594.         }
  595.     }
  596.     if (y > 0) {            /* If there is any text (left), */
  597.         for (x = 0; x < y; x++) {    /* make sure they included "%s" */
  598.         if (s[x] != '%') continue;
  599.         if (s[x+1] == 's') break;
  600.         }
  601.         if (x == y) {
  602.         printf(
  603. "?Dial-command must contain \"%cs\" for phone number.\n",'%');
  604.         return(-9);
  605.         }
  606.     }
  607.     if (dialcmd) {            /* Free any previous string. */
  608.         free(dialcmd);
  609.         dialcmd = (char *) 0;
  610.     }    
  611.     if (y > 0) {
  612.         dialcmd = malloc(y + 1);    /* Allocate space for it */
  613.         strcpy(dialcmd,s);        /* and make a safe copy. */
  614.     }
  615.     return(success = 1);
  616.       case XYDKSP:            /* DIAL KERMIT-SPOOF */
  617.     return(success = seton(&dialksp));
  618.       case XYDTMO:            /* DIAL TIMEOUT */
  619.     y = cmnum("Seconds to wait for call completion","0",10,&x,xxstring);
  620.     return(success = setnum(&dialtmo,x,y,10000));
  621.       case XYDDPY:            /* DIAL DISPLAY */
  622.     return(success = seton(&dialdpy));
  623.       case XYDSPD:            /* DIAL SPEED-MATCHING */
  624.                     /* used to be speed-changing */
  625.     if ((y = seton(&mdmspd)) < 0) return(y);
  626. #ifdef COMMENT
  627.     mdmspd = 1 - mdmspd;        /* so here we reverse the meaning */
  628. #endif /* COMMENT */
  629.     return(success = 1);
  630.       case XYDMNP:            /* DIAL MNP-ENABLE */
  631.     return(success = seton(&dialmnp));
  632. #ifdef MDMHUP
  633.       case XYDMHU:            /* DIAL MODEM-HANGUP */
  634.     return(success = seton(&dialmhu));
  635. #endif /* MDMHUP */
  636.       case XYDDIR:            /* DIAL DIRECTORY */
  637.     if ((y = cmifi("Name of dialing directory file","",&s,&y,
  638.                xxstring)) < 0) {
  639.         if (y == -3) {
  640.         if (dialdir) free(dialdir);    /* Free any previous storage */
  641.         dialdir = NULL;
  642.         return(success = 1);
  643.         } else return(y);
  644.     }
  645.     if (y) {
  646.         printf("?Wildcards not allowed\n");
  647.         return(-9);
  648.     }
  649.     strcpy(line,s);            /* Make safe copy of dial string */
  650.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  651.     if (dialdir) free(dialdir);    /* Free previous filename storage */
  652.     if (dialfd) {            /* Close previous file, if any */
  653.         fclose(dialfd);
  654.         dialfd = NULL;
  655.     }
  656.     s = line;            /* Point back to dial string */
  657.     if (s == NULL || *s == NUL) {    /* If no name given */
  658.         dialdir = NULL;        /* remove the name string */
  659.         return(success = 1);
  660.     } else if ((dialdir = malloc(strlen(s)+1)) == NULL) {
  661.         return(success = 0);    /* Can't malloc storage for name */
  662.     } else {            /* Have storage for name */
  663.         strcpy(dialdir,s);        /* Copy string into new storage */
  664.         if ((dialfd = fopen(dialdir,"r")) == NULL) { /* Open the file */
  665.         perror(dialdir);    /* Can't, print message saying why */
  666.         success = 0;        /* We didn't succeed */
  667.         return(-9);        /* Fail, message already printed */
  668.         }
  669.         return(success = 1);    /* Everything is OK */
  670.     }
  671.  
  672.       default:
  673.     printf("?Unexpected SET DIAL parameter\n");
  674.     return(-2);
  675.     }
  676. }
  677. #endif /* NODIAL */
  678.  
  679. int
  680. setfil(rmsflg) int rmsflg; {
  681.     if (rmsflg) {
  682.     if ((y = cmkey(rfiltab,nrfilp,"Remote file parameter","",
  683.                xxstring)) < 0) {
  684.         if (y == -3) {
  685.         printf("?Remote file parameter required\n");
  686.         return(-9);
  687.         } else return(y);
  688.     }
  689.     } else {
  690.     if ((y = cmkey(filtab,nfilp,"File parameter","",xxstring)) < 0)
  691.       return(y);
  692.     }
  693.     switch (y) {
  694. #ifdef COMMENT                /* Not needed */
  695.       case XYFILB:            /* Blocksize */
  696.     sprintf(tmpbuf,"%d",DBLKSIZ);
  697.     if ((y = cmnum("file block size",tmpbuf,10,&z,xxstring)) < 0)
  698.       return(y);
  699.     if ((x = cmcfm()) < 0) return(x);
  700.     if (rmsflg) {
  701.         sprintf(tmpbuf,"%d",z);
  702.         sstate = setgen('S', "311", tmpbuf, "");
  703.         return((int) sstate);
  704.     } else {
  705.         fblksiz = z;
  706.         return(success = 1);
  707.     }
  708. #endif /* COMMENT */
  709.  
  710.       case XYFILS:            /* Byte size */
  711.     if ((y = cmnum("file byte size (7 or 8)","8",10,&z,xxstring)) < 0)
  712.       return(y);
  713.     if (z != 7 && z != 8) {
  714.         printf("\n?The choices are 7 and 8\n");
  715.         return(0);
  716.     }
  717.     if ((y = cmcfm()) < 0) return(y);
  718.     if (z == 7) fmask = 0177;
  719.     else if (z == 8) fmask = 0377;
  720.     return(success = 1);
  721.  
  722. #ifndef NOCSETS
  723.       case XYFILC:            /* Character set */
  724.     if ((x = cmkey(fcstab,nfilc,"local file code","ascii", xxstring)) < 0)
  725.       return(x);
  726.     if ((z = cmcfm()) < 0) return(z);
  727.     fcharset = x;
  728.     return(success = 1);
  729. #endif /* NOCSETS */
  730.  
  731.       case XYFILD:            /* Display */
  732.     if ((x = cmkey(fdtab,nfdtab,"file transfer display style","",
  733.                xxstring)) < 0)
  734.       return(x);
  735.     if ((z = cmcfm()) < 0) return(z);
  736. #ifdef CK_CURSES
  737.     if (x == XYFD_C) {
  738. #ifdef VMS
  739.         lp = line;
  740. #else
  741.         lp = trmbuf;
  742. #endif /* VMS */
  743. #ifndef MYCURSES
  744.         s = getenv("TERM");
  745.         if (tgetent(lp,s) < 1) {
  746. #ifdef VMS
  747.         printf("Sorry, terminal type not supported: %s\n",s);
  748. #else
  749.         printf("Sorry, terminal type unknown: %s\n",s);
  750. #endif /* VMS */
  751.         return(success = 0);
  752.         }
  753. #endif /* MYCURSES */
  754.         line[0] = '\0';
  755.     }
  756. #endif /* CK_CURSES */
  757.     fdispla = x;            /* It's OK. */
  758.     return(success = 1);
  759.  
  760.       case XYFILN:            /* Names */
  761.     if ((x = cmkey(fntab,2,"how to handle filenames","converted",
  762.                xxstring)) < 0)
  763.       return(x);
  764.     if ((z = cmcfm()) < 0) return(z);
  765.     if (rmsflg) {
  766.         sprintf(tmpbuf,"%d",1 - x);
  767.         sstate = setgen('S', "301", tmpbuf, "");
  768.         return((int) sstate);
  769.     } else {
  770.         fncnv = x;
  771.         return(success = 1);
  772.     }
  773.  
  774.       case XYFILR:            /* Record length */
  775.     sprintf(tmpbuf,"%d",DLRECL);
  776.     if ((y = cmnum("file record length",tmpbuf,10,&z,xxstring)) < 0)
  777.       return(y);
  778.     if ((x = cmcfm()) < 0) return(x);
  779.     if (rmsflg) {
  780.         sprintf(tmpbuf,"%d",z);
  781.         sstate = setgen('S', "312", tmpbuf, "");
  782.         return((int) sstate);
  783.     } else {
  784.         frecl = z;
  785.         return(success = 1);
  786.     }
  787.  
  788. #ifdef COMMENT
  789.       case XYFILO:            /* Organization */
  790.     if ((x = cmkey(forgtab,nforg,"file organization","sequential",
  791.                xxstring)) < 0)
  792.       return(x);
  793.     if ((y = cmcfm()) < 0) return(y);
  794.     if (rmsflg) {
  795.         sprintf(tmpbuf,"%d",x);
  796.         sstate = setgen('S', "314", tmpbuf, "");
  797.         return((int) sstate);
  798.     } else {
  799.         forg = x;
  800.         return(success = 1);
  801.     }    
  802. #endif /* COMMENT */
  803.  
  804. #ifdef COMMENT                /* Not needed */
  805.       case XYFILF:            /* Format */
  806.     if ((x = cmkey(frectab,nfrec,"file record format","stream",
  807.                xxstring)) < 0)
  808.       return(x);
  809.     if ((y = cmcfm()) < 0) return(y);
  810.     if (rmsflg) {
  811.         sprintf(tmpbuf,"%d",x);
  812.         sstate = setgen('S', "313", tmpbuf, "");
  813.         return((int) sstate);
  814.     } else {
  815.         frecfm = x;
  816.         return(success = 1);
  817.     }
  818. #endif /* COMMENT */
  819.  
  820. #ifdef COMMENT
  821.       case XYFILP:            /* Printer carriage control */
  822.     if ((x = cmkey(fcctab,nfcc,"file carriage control","newline",
  823.                xxstring)) < 0)
  824.       return(x);
  825.     if ((y = cmcfm()) < 0) return(y);
  826.     if (rmsflg) {
  827.         sprintf(tmpbuf,"%d",x);
  828.         sstate = setgen('S', "315", tmpbuf, "");
  829.         return((int) sstate);
  830.     } else {
  831.         fcctrl = x;
  832.         return(success = 1);
  833.     }    
  834. #endif /* COMMENT */
  835.  
  836.       case XYFILT:            /* Type */
  837.     if ((x = cmkey(fttab,nfttyp,"type of file","text",xxstring)) < 0)
  838.       return(x);
  839. #ifdef COMMENT
  840.     if ((y = cmnum("file byte size (7 or 8)","8",10,&z,xxstring)) < 0)
  841.       return(y);
  842.     if (z != 7 && z != 8) {
  843.         printf("\n?The choices are 7 and 8\n");
  844.         return(0);
  845.     }
  846. #endif /* COMMENT */
  847.  
  848. #ifdef VMS
  849.         /* Allow VMS users to choose record format for binary files */
  850.         if ((x == XYFT_B) && (rmsflg == 0)) {
  851.         if ((x = cmkey(fbtab,nfbtyp,"VMS record format","fixed",
  852.                xxstring)) < 0)
  853.           return(x);
  854.     }
  855. #endif /* VMS */
  856.     if ((y = cmcfm()) < 0) return(y);
  857.     if (rmsflg) {
  858.         sstate = setgen('S', "300", x ? "1" : "0", "");
  859.         return((int) sstate);
  860.     } else {
  861.         binary = x;
  862. #ifdef COMMENT
  863.         if (z == 7) fmask = 0177;
  864.         else if (z == 8) fmask = 0377;
  865. #endif /* COMMENT */
  866.         return(success = 1);
  867.     }
  868.  
  869.       case XYFILX:            /* Collision Action */
  870.     if ((x = cmkey(colxtab,ncolx,"Filename collision action","backup",
  871.                xxstring)) < 0)
  872.       return(x);
  873.     if ((y = cmcfm()) < 0) return(y);
  874.     fncact = x;
  875.     if (rmsflg) {
  876.         sprintf(tmpbuf,"%d",fncact);
  877.         sstate = setgen('S', "302", tmpbuf, "");
  878.         return((int) sstate);
  879.     } else {
  880.         if (fncact == XYFX_R) warn = 1; /* SET FILE WARNING implications */
  881.         if (fncact == XYFX_X) warn = 0; /* ... */
  882.         return(success = 1);
  883.     }
  884.  
  885.       case XYFILW:            /* Warning/Write-Protect */
  886.     seton(&warn);
  887.     if (warn)
  888.       fncact = XYFX_R;
  889.     else
  890.       fncact = XYFX_X;
  891.     return(success = 1);
  892.  
  893. #ifdef VMS
  894.       case XYFILL:            /* LABELED FILE parameters */
  895.     if ((x = cmkey(lbltab,nlblp,"VMS labeled file feature","",
  896.                xxstring)) < 0)
  897.       return(x);
  898.     if ((success = seton(&y)) < 0)
  899.       return(success);
  900.     if (y)                /* Set or reset the selected bit */
  901.       lf_opts |= x;            /* in the options bitmask. */
  902.     else
  903.       lf_opts &= ~x;
  904.     return(success);
  905. #endif /* VMS */
  906.  
  907.       case XYFILI:            /* INCOMPLETE */
  908.     return(doprm(XYIFD,rmsflg));
  909.  
  910.       default:
  911.     printf("?unexpected file parameter\n");
  912.     return(-2);
  913.     }
  914. }
  915.  
  916. int
  917. settrm() {
  918.     if ((y = cmkey(trmtab,ntrm,"","",xxstring)) < 0) return(y);
  919. #ifdef MAC
  920.     printf("\n?Sorry, not implemented yet.  Please use the Settings menu.\n");
  921.     return(-9);
  922. #else
  923.     switch (y) {
  924.       case XYTBYT:            /* SET TERMINAL BYTESIZE */
  925.     if ((y = cmnum("bytesize for terminal connection","8",10,&x,
  926.                xxstring)) < 0)
  927.       return(y);
  928.     if (x != 7 && x != 8) {
  929.         printf("\n?The choices are 7 and 8\n");
  930.         return(success = 0);
  931.     }
  932.     if ((y = cmcfm()) < 0) return(y);
  933.     if (x == 7) cmask = 0177;
  934.     else if (x == 8) cmask = 0377;
  935.         return(success = 1);
  936.  
  937.       case XYTSO:            /* SET TERMINAL LOCKING-SHIFT */
  938.     return(success = seton(&sosi));
  939.  
  940.       case XYTNL:            /* SET TERMINAL NEWLINE-MODE */
  941.     return(success = seton(&tnlm)); 
  942.  
  943. #ifdef OS2
  944.       case XYTCOL:            /* SET TERMINAL COLOR */
  945.     if ((x = cmkey(ttycoltab,ncolors,"","normal",xxstring)) < 0) {
  946.         return(x);
  947.         } else {
  948.         extern int colornormal, colorreverse, colorunderline,
  949.           colorstatus, colorhelp, scrninitialised;
  950.         int fg, bg;
  951.         if ((fg = cmkey(ttyclrtab,nclrs,
  952.                 "foreground color","black",xxstring)) < 0)
  953.           return(fg);
  954.         if ((bg = cmkey(ttyclrtab,nclrs,
  955.                 "background color","cyan",xxstring)) < 0)
  956.           return(bg);
  957.         if ((y = cmcfm()) < 0)
  958.           return(y);
  959.         switch (x) {
  960.           case 0:
  961.         colornormal = fg | bg << 4;
  962.         break;
  963.           case 1:
  964.         colorreverse = fg | bg << 4;
  965.         break;
  966.           case 2:
  967.         colorunderline = fg | bg << 4;
  968.         break;
  969.           case 3:
  970.         colorstatus = fg | bg << 4;
  971.         break;
  972.           case 4:
  973.         colorhelp = fg | bg << 4;
  974.         break;
  975.           default:
  976.         printf("%s - invalid\n",cmdbuf);
  977.         return(-9);
  978.         break;
  979.         }
  980.         scrninitialised = 0;
  981.         }
  982.     return(success = 1);
  983.  
  984.       case XYTCUR:            /* SET TERMINAL CURSOR */
  985.     if ((x = cmkey(ttycurtab,ncursors,"","underline",xxstring)) < 0)
  986.       return(x);
  987.     if ((y = cmcfm()) < 0) return(y);
  988.         tt_cursor = x;
  989.     return(success = 1);
  990.  
  991.       case XYTTYP:            /* SET TERMINAL TYPE */
  992.     if ((x = cmkey(ttyptab,nttyp,"","vt102",xxstring)) < 0) return(x);
  993.     if ((y = cmcfm()) < 0) return(y);
  994.     tt_type = x;
  995.     return(success = 1);
  996.  
  997.       case XYTARR:            /* SET TERMINAL ARROW-KEYS */
  998.     if ((x = cmkey(akmtab,2,"","",xxstring)) < 0) return(x);
  999.     if ((y = cmcfm()) < 0) return(y);
  1000.     tt_arrow = x;            /* 0 = application, 1 = cursor */
  1001.     return(success = 1);
  1002.  
  1003.       case XYTKPD:            /* SET TERMINAL KEYPAD-MODE */
  1004.     if ((x = cmkey(kpmtab,2,"","",xxstring)) < 0) return(x);
  1005.     if ((y = cmcfm()) < 0) return(y);
  1006.     tt_keypad = x;            /* 0 = application, 1 = numeric */
  1007.     return(success = 1);
  1008.  
  1009.       case XYTWRP:            /* SET TERMINAL WRAP */
  1010.     seton(&tt_wrap);
  1011.     return(success = 1);    
  1012.  
  1013.       case XYSCRS:
  1014.     if ((y = cmnum("scrollback buffer size for terminal mode","240",10,&x,
  1015.                xxstring)) < 0)
  1016.       return(y);
  1017. #ifdef __32BIT__
  1018.     if (x < 64 || x > 4096) {
  1019.         printf("\n?The size must be between 64 and 4096\n");
  1020.         return(success = 0);
  1021.     }
  1022. #else
  1023.     if (x < 64 || x > 240) {
  1024.         printf("\n?The size must be between 64 and 240\n");
  1025.         return(success = 0);
  1026.     }
  1027. #endif /* __32BIT__ */
  1028.     if ((y = cmcfm()) < 0) return(y);
  1029.     tt_scrsize = x;
  1030.     return(success = 1);
  1031. #endif /* OS2 */
  1032.  
  1033. #ifndef NOCSETS
  1034.       case XYTCS:            /* SET TERMINAL CHARACTER-SET */
  1035.     /* set terminal character-set <remote> <local> */
  1036.     if ((x = cmkey(ttcstab,ntermc,
  1037.                "remote terminal character-set","",xxstring)) < 0) 
  1038.       return(x);
  1039.     if (x == FC_TRANSP) {        /* TRANSPARENT? */
  1040.         if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
  1041.         tcsr = tcsl = FC_USASCII;    /* Make them both the same */
  1042.         return(success = 1);
  1043.     }
  1044.  
  1045. /* Not transparent, so get local set to translate it into */
  1046.  
  1047.     s = "";                /* Make current file char set */
  1048.     for (y = 0; y <= nfilc; y++)    /* be the default... */
  1049.       if (fcstab[y].kwval == fcharset) {
  1050.           s = fcstab[y].kwd;
  1051.           break;
  1052.         }
  1053.     if ((y = cmkey(fcstab,nfilc,
  1054.                "local character-set",s,xxstring)) < 0)
  1055.       return(y);
  1056.     if ((z = cmcfm()) < 0) return(z); /* Confirm the command */
  1057.     tcsr = x;            /* Remote character set */
  1058.     tcsl = y;            /* Local character set */
  1059.     return(success = 1);
  1060. #endif /* NOCSETS */
  1061.  
  1062.       case XYTEC:            /* SET TERMINAL ECHO */
  1063.     if ((x = cmkey(rltab,nrlt,"which side echos during CONNECT",
  1064.                "remote", xxstring)) < 0) return(x);
  1065.     if ((y = cmcfm()) < 0) return(y);
  1066.     duplex = x;
  1067.     return(success = 1); 
  1068.  
  1069.       case XYTCRD:            /* SET TERMINAL CR-DISPLAY */
  1070.     if ((x = cmkey(crdtab,2,"", "normal", xxstring)) < 0) return(x);
  1071.     if ((y = cmcfm()) < 0) return(y);
  1072.     tt_crd = x;
  1073.     return(success = 1); 
  1074.  
  1075. #ifdef OS2
  1076.       case XYTANS:            /* SET TERMINAL ANSWERBACK */
  1077. /*
  1078.   NOTE: We let them enable and disable the answerback sequence, but we
  1079.   do NOT let them change it, and we definitely do not let the host set it.
  1080.   This is a security feature.
  1081. */
  1082.     seton(&tt_answer);
  1083.     return(success = 1);    
  1084. #endif /* OS2 */
  1085.  
  1086.       default:                /* Shouldn't get here. */
  1087.     return(-2);
  1088.     }    
  1089. #endif /* MAC */
  1090. }
  1091.  
  1092. int                    /* SET SEND/RECEIVE */
  1093. setsr(xx, rmsflg) int xx; int rmsflg; {
  1094.     if (xx == XYRECV)
  1095.         strcpy(line,"Parameter for inbound packets");
  1096.     else
  1097.         strcpy(line,"Parameter for outbound packets");
  1098.  
  1099.     if (rmsflg) {
  1100.     if ((y = cmkey(rsrtab,nrsrtab,line,"",xxstring)) < 0) {
  1101.         if (y == -3) {
  1102.         printf("?Remote receive parameter required\n");
  1103.         return(-9);
  1104.         } else return(y);
  1105.     }
  1106.     } else {
  1107.     if ((y = cmkey(srtab,nsrtab,line,"",xxstring)) < 0) return(y);
  1108.     }
  1109.     switch (y) {
  1110.       case XYQCTL:            /* CONTROL-PREFIX */
  1111.     if ((x = cmnum("ASCII value of control prefix","",10,&y,xxstring)) < 0)
  1112.       return(x);
  1113.     if ((x = cmcfm()) < 0) return(x);
  1114.     if ((y > 32 && y < 63) || (y > 95 && y < 127)) {
  1115.         if (xx == XYRECV)
  1116.           ctlq = (CHAR) y;        /* RECEIVE prefix, use with caution! */
  1117.         else
  1118.           myctlq = (CHAR) y;    /* SEND prefix, OK to change */
  1119.         return(success = 1); 
  1120.     } else {
  1121.         printf("?Illegal value for prefix character\n");
  1122.         return(-9);
  1123.     }
  1124.  
  1125.       case XYEOL:
  1126.     y = cmnum("Decimal ASCII code for packet terminator","13",10,&x,
  1127.           xxstring);
  1128.     if ((y = setcc(&z,x,y)) < 0) return(y);
  1129.     if (z > 31) {
  1130.         printf("Sorry, the legal values are 0-31\n");
  1131.         return(-9);
  1132.     }
  1133.     if (xx == XYRECV) eol = z; else {
  1134.         seol = z;
  1135.     }
  1136.     return(success = y);
  1137.  
  1138.       case XYLEN:
  1139.     y = cmnum("Maximum number of characters in a packet","90",10,&x,
  1140.           xxstring);
  1141.     if (xx == XYRECV) {        /* Receive... */
  1142.         if ((y = setnum(&z,x,y,maxrps)) < 0)
  1143.           return(y);
  1144.         if (z < 10) {
  1145.         printf("Sorry, 10 is the minimum\n");
  1146.         return(-9);
  1147.         }
  1148.         if (rmsflg) {
  1149.         tp = tmpbuf;
  1150.         sprintf(tp,"%d",z);
  1151.         sstate = setgen('S', "401", tp, "");
  1152.         return((int) sstate);
  1153.         } else {
  1154.         if (z > MAXRP) z = MAXRP;
  1155.         y = adjpkl(z,wslotr,bigrbsiz);
  1156.         if (y != z) {
  1157.             urpsiz = y;
  1158.             if (
  1159. #ifndef NOSPL
  1160.             cmdlvl == 0
  1161. #else
  1162.             tlevel < 0
  1163. #endif /* NOSPL */
  1164.             )
  1165.               if (msgflg) printf(
  1166. " Adjusting receive packet-length to %d for %d window slots\n",
  1167.              y, wslotr);
  1168.         }
  1169.         urpsiz = y;
  1170.         rpsiz =  (y > 94) ? 94 : y;
  1171.         }
  1172.     } else {            /* Send... */
  1173.         if ((y = setnum(&z,x,y,maxsps)) < 0)
  1174.           return(y);
  1175.         if (z < 10) {
  1176.         printf("Sorry, 10 is the minimum\n");
  1177.         return(-9);
  1178.         }
  1179.         if (z > MAXSP) z = MAXSP;
  1180.         spsiz = z;            /* Set it */
  1181.         y = adjpkl(spsiz,wslotr,bigsbsiz);
  1182.         if (y != spsiz &&
  1183. #ifndef NOSPL
  1184.         cmdlvl == 0
  1185. #else
  1186.         tlevel < 0
  1187. #endif /* NOSPL */
  1188.         )
  1189.           if (msgflg)
  1190.         printf("Adjusting packet size to %d for %d window slots\n",
  1191.              y,wslotr);
  1192.         spsiz = spmax = spsizr = y;    /* Set it and flag that it was set */
  1193.         spsizf = 1;            /* to allow overriding Send-Init. */
  1194.     }
  1195.     if (pflag &&
  1196. #ifndef NOSPL
  1197.         cmdlvl == 0
  1198. #else
  1199.         tlevel < 0
  1200. #endif /* NOSPL */
  1201.         ) {
  1202.         if (z > 94 && msgflg) {
  1203.         printf("Extended-length packets requested.\n");
  1204.         if (bctr < 2 && z > 200) printf("\
  1205. Remember to SET BLOCK 2 or 3 for long packets.\n");
  1206.         }
  1207.         if (speed <= 0L) speed = ttgspd();
  1208. #ifdef COMMENT
  1209. /*
  1210.   Kermit does this now itself.
  1211. */
  1212.         if (speed <= 0L && z > 200 && msgflg) {
  1213.         printf("\
  1214. Make sure your timeout interval is long enough for %d-byte packets.\n",z);
  1215.         }
  1216. #endif /* COMMENT */
  1217.     }
  1218.     return(success = y);
  1219.  
  1220.       case XYMARK:
  1221.     y = cmnum("Code for packet-start character","1",10,&x,xxstring);
  1222. #ifdef UNIX
  1223. /*
  1224.   Printable start-of-packet works for UNIX and VMS only!
  1225. */
  1226.     if ((y = setnum(&z,x,y,126)) < 0) return(y);
  1227. #else
  1228. #ifdef VMS
  1229.     if ((y = setnum(&z,x,y,126)) < 0) return(y);
  1230. #else
  1231.     if ((y = setcc(&z,x,y)) < 0) return(y);
  1232. #endif /* VMS */
  1233. #endif /* UNIX */
  1234.     if (xx == XYRECV) stchr = z; else {
  1235.         mystch = z;
  1236.     }
  1237.     return(success = y);
  1238.  
  1239.       case XYNPAD:            /* PADDING */
  1240.     y = cmnum("How many padding characters for inbound packets","0",10,&x,
  1241.           xxstring);
  1242.     if ((y = setnum(&z,x,y,94)) < 0) return(y);
  1243.     if (xx == XYRECV) mypadn = z; else npad = z;
  1244.     return(success = y);
  1245.  
  1246.       case XYPADC:            /* PAD-CHARACTER */
  1247.     y = cmnum("Decimal ASCII code for packet padding character","0",10,&x,
  1248.           xxstring);
  1249.     if ((y = setcc(&z,x,y)) < 0) return(y);
  1250.     if (xx == XYRECV) mypadc = z; else padch = z;
  1251.     return(success = y);
  1252.  
  1253.       case XYTIMO:            /* TIMEOUT */
  1254.     if (xx == XYRECV) {
  1255.         char buf[16];        /* Construct default */
  1256.         sprintf(buf,"%d",URTIME);
  1257.         y = cmnum("Packet timeout interval",buf,10,&x,xxstring);
  1258.         if ((y = setnum(&z,x,y,94)) < 0) return(y);
  1259.  
  1260.         if (rmsflg) {        /* REMOTE SET RECEIVE TIMEOUT */
  1261.         tp = tmpbuf;        /*   Tell Kermit server what */
  1262.         sprintf(tp,"%d",z);    /*   timeout to ask me to use. */
  1263.         sstate = setgen('S', "402", tp, "");
  1264.         return((int) sstate);
  1265.         } else {            /* SET RECEIVE TIMEOUT */
  1266.         pkttim = z;        /*   Value to put in my negotiation */
  1267.         }                /*   packet for other Kermit to use */
  1268.  
  1269.     } else {            /* SET SEND TIMEOUT */
  1270.         y = cmnum("Packet timeout interval","",10,&x,xxstring);
  1271.         if (y == -3) {        /* They cancelled a previous */
  1272.         x = DMYTIM;        /* SET SEND command, so restore */
  1273.         y = 0;            /* the default */
  1274.         timef = 0;        /* and turn off the override flag */
  1275.         } else {            /* They gave a number */
  1276.         timef = 1;        /* so turn on the override flag */
  1277.         }
  1278.         if ((y = setnum(&z,x,y,94)) < 0)
  1279.           return(y);
  1280.         timint = rtimo = z;        /* Override value for me to use */
  1281.     }
  1282.     return(success = 1);
  1283.  
  1284.       default:
  1285.     return(-2);
  1286.     }                    /* End of SET SEND/RECEIVE... */
  1287. }
  1288.  
  1289. #ifndef NOXMIT
  1290. int
  1291. setxmit() {
  1292.     if ((y = cmkey(xmitab,nxmit,"","",xxstring)) < 0) return(y);
  1293.     switch (y) {
  1294.       case XMITE:            /* EOF */
  1295.     y = cmtxt("Characters to send at end of file,\n\
  1296.  Use backslash codes for control characters","",&s,xxstring);
  1297.     if (y < 0) return(y);
  1298.     if ((int)strlen(s) > XMBUFL) {
  1299.         printf("?Too many characters, %d maximum\n",XMBUFL);
  1300.         return(-2);
  1301.     }
  1302.     strcpy(xmitbuf,s);
  1303.     return(success = 1);
  1304.  
  1305.       case XMITF:            /* Fill */
  1306.     y = cmnum("Numeric code for blank-line fill character","0",10,&x,
  1307.           xxstring);
  1308.     if ((y = setnum(&z,x,y,127)) < 0) return(y);
  1309.     xmitf = z;
  1310.     return(success = 1);
  1311.       case XMITL:            /* Linefeed */
  1312.         return(success = seton(&xmitl));
  1313.       case XMITS:            /* Locking-Shift */
  1314.         return(success = seton(&xmits));
  1315.       case XMITP:            /* Prompt */
  1316.     y = cmnum("Numeric code for host's prompt character, 0 for none",
  1317.           "10",10,&x,xxstring);
  1318.     if ((y = setnum(&z,x,y,127)) < 0) return(y);
  1319.     xmitp = z;
  1320.     return(success = 1);
  1321.       case XMITX:            /* Echo */
  1322.         return(success = seton(&xmitx));
  1323.       case XMITW:            /* Pause */
  1324.     y = cmnum("Number of milliseconds to pause between binary characters\n\
  1325. or text lines during transmission","0",10,&x,xxstring);
  1326.     if ((y = setnum(&z,x,y,1000)) < 0) return(y);
  1327.     xmitw = z;
  1328.     return(success = 1);
  1329.       default:
  1330.     return(-2);
  1331.     }
  1332. }
  1333. #endif /* NOXMIT */
  1334.  
  1335. /*  D O R M T  --  Do a remote command  */
  1336.  
  1337. #ifdef ATTSV
  1338. #ifndef aegis
  1339. #ifndef datageneral
  1340. #define CK_NEED_SIG
  1341. #endif /* datageneral */
  1342. #endif /* aegis */
  1343. #endif /* ATTSV */
  1344.  
  1345. VOID rmsg() {
  1346.     if (pflag)
  1347.       printf(
  1348. #ifdef CK_NEEDSIG
  1349.  
  1350.        " Type your escape character, %s, followed by X or E to cancel.\n",
  1351.        dbchr(escape)
  1352. #else
  1353.        " Press the X or E key to cancel.\n"
  1354. #endif /* CK_NEEDSIG */
  1355.       );
  1356. }
  1357.  
  1358. int
  1359. dormt(xx) int xx; {
  1360.     int x, y, retcode;
  1361.     char *s, sbuf[50], *s2;
  1362.  
  1363.  
  1364.     if (xx < 0) return(xx);
  1365.  
  1366.     if (xx == XZSET) {            /* REMOTE SET */
  1367.     if ((y = cmkey(rmstab,nrms,"","",xxstring)) < 0) {
  1368.         if (y == -3) {
  1369.         printf("?Parameter name required\n");
  1370.         return(-9);
  1371.         } else return(y);
  1372.     }
  1373.     return(doprm(y,1));
  1374.     }
  1375.  
  1376.     switch (xx) {            /* Others... */
  1377.  
  1378. case XZCWD:                /* CWD */
  1379.     if ((x = cmtxt("Remote directory name","",&s,xxstring)) < 0) return(x);
  1380.     debug(F111,"XZCWD: ",s,x);
  1381.     *sbuf = NUL;
  1382.     s2 = sbuf;
  1383.  
  1384. /* The following is commented out, because there is practically no */
  1385. /* computer in the world that requires a password for directory changing. */
  1386. /* (The DEC-20 was the only one, and they're mostly all gone.) */
  1387. #ifdef DIRPWDPR
  1388.     if (*s != NUL) {            /* If directory name given, */
  1389.                     /* get password on separate line. */
  1390.         if (tlevel > -1) {        /* From take file... */
  1391.  
  1392.         if (fgets(sbuf,50,tfile[tlevel]) == NULL)
  1393.             fatal("take file ends prematurely in 'remote cwd'");
  1394.         debug(F110," pswd from take file",s2,0);
  1395.         for (x = (int)strlen(sbuf);
  1396.               x > 0 && (sbuf[x-1] == NL || sbuf[x-1] == CR);
  1397.          x--)
  1398.         sbuf[x-1] = '\0';
  1399.  
  1400.         } else {            /* From terminal... */
  1401.  
  1402.         printf(" Password: ");         /* get a password */
  1403. #ifdef OS2
  1404.         while (((x = isatty(0) ? coninc(0) :
  1405.              getchar()) != NL) && (x != CR)) {     /* with no echo */
  1406. #else
  1407.         while (((x = getchar()) != NL) && (x != CR)) { /* with no echo */
  1408. #endif /* OS2 */
  1409.             if ((x &= 0177) == '?') {
  1410.                 printf("? Password of remote directory\n Password: ");
  1411.             s2 = sbuf;
  1412.             *sbuf = NUL;
  1413.             }
  1414.             else if (x == ESC)    /* Mini command line editor... */
  1415.                 putchar(BEL);
  1416.         else if (x == BS || x == 0177)
  1417.             s2--;
  1418.         else if (x == 025) {    /* Ctrl-U */
  1419.             s2 = sbuf;
  1420.             *sbuf = NUL;
  1421.         }
  1422.             else
  1423.             *s2++ = x;
  1424.             }
  1425.         *s2 = NUL;
  1426.         putchar('\n');
  1427.         }
  1428.         s2 = sbuf;
  1429.     } else s2 = "";
  1430. #endif /* DIRPWDPR */
  1431.  
  1432.     debug(F110," password",s2,0);
  1433.     sstate = setgen('C',s,s2,"");
  1434.     retcode = 0;
  1435.     break;
  1436.  
  1437. case XZDEL:                /* Delete */
  1438.     if ((x = cmtxt("Name of remote file(s) to delete","",&s,xxstring)) < 0) {
  1439.     if (x == -3) {
  1440.         printf("?Name of remote file(s) required\n");
  1441.         return(-9);
  1442.     } else return(x);
  1443.     }
  1444.     if (local) ttflui();        /* If local, flush tty input buffer */
  1445.     retcode = sstate = rfilop(s,'E');
  1446.     break;
  1447.  
  1448. case XZDIR:                /* Directory */
  1449.     if ((x = cmtxt("Remote directory or file specification","",&s,
  1450.            xxstring)) < 0)
  1451.         return(x);
  1452.     if (local) ttflui();        /* If local, flush tty input buffer */
  1453.     rmsg();
  1454.     retcode = sstate = setgen('D',s,"","");
  1455.     break;
  1456.  
  1457. case XZHLP:                /* Help */
  1458.     if ((x = cmcfm()) < 0) return(x);
  1459.     sstate = setgen('H',"","","");
  1460.     retcode = 0;
  1461.     break; 
  1462.  
  1463. #ifndef NOPUSH
  1464. case XZHOS:                /* Host */
  1465.     if ((x = cmtxt("Command for remote system","",&cmarg,xxstring)) < 0)
  1466.       return(x);
  1467.     if ((int)strlen(cmarg) < 1)  {
  1468.     if (x == -3) {
  1469.         printf("?Remote host command required\n");
  1470.         return(-9);
  1471.     } else return(x);
  1472.     }
  1473.     rmsg();
  1474.     retcode = sstate = 'c';
  1475.     break; 
  1476. #endif /* NOPUSH */
  1477.  
  1478. #ifndef NOFRILLS
  1479. case XZKER:
  1480.     if ((x = cmtxt("Command for remote Kermit","",&cmarg,xxstring)) < 0)
  1481.       return(x);
  1482.     if ((int)strlen(cmarg) < 1)  {
  1483.     if (x == -3) {
  1484.         printf("?Remote Kermit command required\n");
  1485.         return(-9);
  1486.     } else return(x);
  1487.     }
  1488.     retcode = sstate = 'k';
  1489.     rmsg();
  1490.     break; 
  1491.  
  1492. case XZLGI: {                /* Login */
  1493.     char *p1, *p2, *p3;
  1494.     if ((x = cmfld("User ID","",&s,xxstring)) < 0) return(x);
  1495.     if ((p1 = malloc((int)strlen(s) + 1)) == NULL) {
  1496.     printf("Internal error: malloc\n");
  1497.     return(-2);
  1498.     } else strcpy(p1,s);
  1499.     if ((x = cmfld("Password","",&s,xxstring)) < 0) return(x);
  1500.     if ((p2 = malloc((int)strlen(s) + 1)) == NULL) {
  1501.     printf("Internal error: malloc\n");
  1502.     return(-2);
  1503.     } else strcpy(p2,s);
  1504.     if ((x = cmtxt("Account or carriage return","",
  1505.            &s,xxstring)) < 0 && x != -3)
  1506.     return(x);
  1507.     if ((p3 = malloc((int)strlen(s) + 1)) == NULL) {
  1508.     printf("Internal error: malloc\n");
  1509.     return(-2);
  1510.     } else strcpy(p3,s);
  1511.     sstate = setgen('I',p1,p2,p3);
  1512.     if (p3) free(p3);
  1513.     if (p2) free(p2);
  1514.     if (p1) free(p1);
  1515.     retcode = 0;
  1516.     break; 
  1517. }
  1518.  
  1519. case XZLGO:                /* Logout */
  1520.     if ((x = cmcfm()) < 0) return(x);
  1521.     sstate = setgen('I',"","","");
  1522.     retcode = 0;
  1523.     break; 
  1524.  
  1525. case XZPRI:                /* Print */
  1526.     if (!atdiso || !atcapr) {        /* Disposition attribute off? */
  1527.     printf("?Disposition Attribute is Off\n");
  1528.     return(-2);
  1529.     }
  1530.     cmarg = "";
  1531.     cmarg2 = "";
  1532.     if ((x = cmifi("Local file(s) to print on remote printer","",&s,&y,
  1533.            xxstring)) < 0) {
  1534.     if (x == -3) {
  1535.         printf("?Name of local file(s) required\n");
  1536.         return(-9);
  1537.     }
  1538.     return(x);
  1539.     }
  1540.     strcpy(line,s);            /* Make a safe copy of filename */
  1541.     *optbuf = NUL;            /* Wipe out any old options */
  1542.     if ((x = cmtxt("Options for remote print command","",&s,xxstring)) < 0)
  1543.       return(x);
  1544.     strcpy(optbuf,s);            /* Make a safe copy of options */
  1545.     if ((int)strlen(optbuf) > 94) {    /* Make sure this is legal */
  1546.     printf("?Option string too long\n");
  1547.     return(-9);
  1548.     }
  1549.     nfils = -1;                /* Expand file list internally */
  1550.     cmarg = line;            /* Point to file list. */
  1551.     rprintf = 1;            /* REMOTE PRINT modifier for SEND */
  1552.     sstate = 's';            /* Set start state to SEND */
  1553.     if (local) displa = 1;
  1554.     retcode = 0;
  1555.     break;
  1556. #endif /* NOFRILLS */
  1557.     
  1558. case XZSPA:                /* Space */
  1559.     if ((x = cmtxt("Confirm, or remote directory name","",&s,xxstring)) < 0)
  1560.       return(x);
  1561.     retcode = sstate = setgen('U',s,"","");
  1562.     break;
  1563.     
  1564. #ifndef NOFRILLS
  1565. case XZTYP:                /* Type */
  1566.     if ((x = cmtxt("Remote file specification","",&s,xxstring)) < 0)
  1567.       return(x);
  1568.     if ((int)strlen(s) < 1) {
  1569.     printf("?Remote filename required\n");
  1570.         return(-9);    
  1571.     }
  1572.     rmsg();
  1573.     retcode = sstate = rfilop(s,'T');
  1574.     break;
  1575. #endif /* NOFRILLS */
  1576.  
  1577. #ifndef NOFRILLS
  1578. case XZWHO:
  1579.     if ((x = cmtxt("Remote user name, or carriage return","",&s,xxstring)) < 0)
  1580.         return(x);
  1581.     retcode = sstate = setgen('W',s,"","");
  1582.     break;
  1583. #endif /* NOFRILLS */
  1584.  
  1585. default:
  1586.         if ((x = cmcfm()) < 0) return(x);
  1587.         printf("?Not implemented - %s\n",cmdbuf);
  1588.         return(-2);
  1589.     }
  1590.     if (local) ttflui();        /* If local, flush tty input buffer */
  1591.     return(retcode);
  1592. }
  1593.  
  1594.  
  1595. /*  R F I L O P  --  Remote File Operation  */
  1596.  
  1597. CHAR
  1598. #ifdef CK_ANSIC
  1599. rfilop(char * s, char t)
  1600. #else
  1601. rfilop(s,t) char *s, t; 
  1602. #endif /* CK_ANSIC */
  1603. /* rfilop */ {
  1604.     if (*s == NUL) {
  1605.     printf("?File specification required\n");
  1606.     return((CHAR) 0);
  1607.     }
  1608.     debug(F111,"rfilop",s,t);
  1609.     return(setgen(t,s,"",""));
  1610. }
  1611.  
  1612. #ifdef SUNX25
  1613. int
  1614. setx25() {
  1615.     if ((y = cmkey(x25tab,nx25,"X.25 call options","",xxstring)) < 0)
  1616.       return(y);
  1617.     switch (y) {
  1618.       case XYUDAT:
  1619.     if ((z = cmkey(onoff,2,"X.25 call user data","",xxstring))
  1620.         < 0) return(z);
  1621.     if (z == 0) {
  1622.         if ((z = cmcfm()) < 0) return(z);
  1623.         cudata = 0;             /* disable call user data */
  1624.         return (success = 1);
  1625.     }
  1626.     if ((x = cmtxt("X.25 call user data string","",&s,xxstring)) < 0)
  1627.       return(x);
  1628.     if ((int)strlen(s) == 0) {
  1629.         return (-3);
  1630.     } else if ((int)strlen(s) > MAXCUDATA) {
  1631.         printf("?The length must be > 0 and <= %d\n",MAXCUDATA);
  1632.         return(-2);
  1633.     }
  1634.     if ((y = cmcfm()) < 0) return(y);
  1635.     strcpy(udata,s);
  1636.     cudata = 1;            /* X.25 call user data specified */
  1637.     return (success = 1);
  1638.       case XYCLOS:
  1639.     if ((z = cmkey(onoff,2,"X.25 closed user group call","",xxstring))
  1640.         < 0) return(z);
  1641.     if (z == 0) {
  1642.         if ((z = cmcfm()) < 0) return(z);
  1643.         closgr = -1;        /* disable closed user group */
  1644.         return (success = 1);
  1645.     }
  1646.     if ((y = cmnum("0 <= cug index >= 99","",10,&x,xxstring)) < 0)
  1647.       return(y);
  1648.     if (x < 0 || x > 99) {
  1649.         printf("?The choices are 0 <= cug index >= 99\n");
  1650.         return(-2);
  1651.     }
  1652.     if ((y = cmcfm()) < 0) return(y);
  1653.     closgr = x;            /* closed user group selected */
  1654.     return (success = 1);
  1655.  
  1656.       case XYREVC:
  1657.     if((z = cmkey(onoff,2,"X.25 reverse charge call","",xxstring)) < 0)
  1658.       return(z);
  1659.     if ((x = cmcfm()) < 0) return(x);
  1660.     revcall = z;
  1661.     return (success = 1);
  1662.     }
  1663. }
  1664.  
  1665. int
  1666. setpadp() {
  1667.     if ((y = cmkey(padx3tab,npadx3,"PAD X.3 parameter name","",xxstring)) < 0)
  1668.       return(y);
  1669.     x = y;
  1670.     switch (x) {
  1671.       case PAD_BREAK_CHARACTER:
  1672.     if ((y = cmnum("PAD break character value","",10,&z,xxstring)) < 0)
  1673.       return(y);
  1674.     if ((y = cmcfm()) < 0) return(y);
  1675.     break;
  1676.       case PAD_ESCAPE:
  1677.     if ((y = cmnum("PAD escape","",10,&z,xxstring)) < 0) return(y);
  1678.     if (z != 0 && z != 1) {
  1679.         printf("?The choices are 0 or 1\n");
  1680.         return(-2);
  1681.     }
  1682.     if ((y = cmcfm()) < 0) return(y);
  1683.     break;
  1684.       case PAD_ECHO:
  1685.      if ((y = cmnum("PAD echo","",10,&z,xxstring)) < 0) return(y);
  1686.     if (z != 0 && z != 1) {
  1687.         printf("?The choices are 0 or 1\n");
  1688.         return(-2);
  1689.     }
  1690.     if ((y = cmcfm()) < 0) return(y);
  1691.     break;
  1692.       case PAD_DATA_FORWARD_CHAR:
  1693.      if ((y = cmnum("PAD data forward char","",10,&z,xxstring)) < 0)
  1694.       return(y);
  1695.     if (z != 0 && z != 2) {
  1696.         printf("?The choices are 0 or 2\n");
  1697.         return(-2);
  1698.     }
  1699.     if ((y = cmcfm()) < 0) return(y);
  1700.     break;
  1701.       case PAD_DATA_FORWARD_TIMEOUT:
  1702.      if ((y = cmnum("PAD data forward timeout","",10,&z,xxstring)) < 0)
  1703.         return(y);
  1704.     if (z < 0 || z > 255) {
  1705.         printf("?The choices are 0 or 1 <= timeout <= 255\n");
  1706.         return(-2);
  1707.     }
  1708.     if ((y = cmcfm()) < 0) return(y);
  1709.     break;
  1710.       case PAD_FLOW_CONTROL_BY_PAD:
  1711.      if ((y = cmnum("PAD pad flow control","",10,&z,xxstring)) < 0)
  1712.       return(y);
  1713.     if (z != 0 && z != 1) {
  1714.         printf("?The choices are 0 or 1\n");
  1715.         return(-2);
  1716.     }
  1717.     if ((y = cmcfm()) < 0) return(y);
  1718.     break;
  1719.       case PAD_SUPPRESSION_OF_SIGNALS:
  1720.      if ((y = cmnum("PAD service","",10,&z,xxstring)) < 0) return(y);
  1721.     if (z != 0 && z != 1) {
  1722.         printf("?The choices are 0 or 1\n");
  1723.         return(-2);
  1724.     }
  1725.     if ((y = cmcfm()) < 0) return(y);
  1726.     break;
  1727.  
  1728.       case PAD_BREAK_ACTION:
  1729.      if ((y = cmnum("PAD break action","",10,&z,xxstring)) < 0) return(y);
  1730.     if (z != 0 && z != 1 && z != 2 && z != 5 && z != 8 && z != 21) {
  1731.         printf("?The choices are 0, 1, 2, 5, 8 or 21\n");
  1732.         return(-2);
  1733.     }
  1734.     if ((y = cmcfm()) < 0) return(y);
  1735.     break;
  1736.  
  1737.       case PAD_SUPPRESSION_OF_DATA:
  1738.      if ((y = cmnum("PAD data delivery","",10,&z,xxstring)) < 0) return(y);
  1739.     if (z != 0 && z != 1) {
  1740.         printf("?The choices are 0 or 1\n");
  1741.         return(-2);
  1742.     }
  1743.     if ((y = cmcfm()) < 0) return(y);
  1744.     break;
  1745.  
  1746.       case PAD_PADDING_AFTER_CR:
  1747.      if ((y = cmnum("PAD crpad","",10,&z,xxstring)) < 0) return(y);
  1748.     if (z < 0 || z > 7) {
  1749.         printf("?The choices are 0 or 1 <= crpad <= 7\n");
  1750.         return(-2);
  1751.     }
  1752.     if ((y = cmcfm()) < 0) return(y);
  1753.     break;
  1754.  
  1755.       case PAD_LINE_FOLDING:
  1756.      if ((y = cmnum("PAD linefold","",10,&z,xxstring)) < 0) return(y);
  1757.     if (z < 0 || z > 255) {
  1758.         printf("?The choices are 0 or 1 <= linefold <= 255\n");
  1759.         return(-2);
  1760.     }
  1761.     if ((y = cmcfm()) < 0) return(y);
  1762.     break;
  1763.  
  1764.       case PAD_LINE_SPEED:
  1765.      if ((y = cmnum("PAD baudrate","",10,&z,xxstring)) < 0) return(y);
  1766.     if (z < 0 || z > 18) {
  1767.         printf("?The choices are 0 <= baudrate <= 18\n");
  1768.         return(-2);
  1769.     }
  1770.     if ((y = cmcfm()) < 0) return(y);
  1771.     break;
  1772.  
  1773.       case PAD_FLOW_CONTROL_BY_USER:
  1774.      if ((y = cmnum("PAD terminal flow control","",10,&z,xxstring)) < 0)
  1775.         return(y);
  1776.     if (z != 0 && z != 1) {
  1777.         printf("?The choices are 0 or 1\n");
  1778.         return(-2);
  1779.     }
  1780.     if ((y = cmcfm()) < 0) return(y);
  1781.     break;
  1782.  
  1783.       case PAD_LF_AFTER_CR:
  1784.      if ((y = cmnum("PAD crpad","",10,&z,xxstring)) < 0) return(y);
  1785.     if (z < 0 || z == 3 || z > 7) {
  1786.         printf("?The choices are 0, 1, 2, 4, 5, 6 or 7\n");
  1787.         return(-2);
  1788.     }
  1789.     if ((y = cmcfm()) < 0) return(y);
  1790.     break;
  1791.  
  1792.       case PAD_PADDING_AFTER_LF:
  1793.      if ((y = cmnum("PAD lfpad","",10,&z,xxstring)) < 0) return(y);
  1794.     if (z < 0 || z > 7) {
  1795.         printf("?The choices are 0 or 1 <= lfpad <= 7\n");
  1796.         return(-2);
  1797.     }
  1798.     if ((y = cmcfm()) < 0) return(y);
  1799.     break;
  1800.  
  1801.       case PAD_EDITING:
  1802.      if ((y = cmnum("PAD edit control","",10,&z,xxstring)) < 0) return(y);
  1803.     if (z != 0 && z != 1) {
  1804.         printf("?The choices are 0 or 1\n");
  1805.         return(-2);
  1806.     }
  1807.     if ((y = cmcfm()) < 0) return(y);
  1808.     break;
  1809.  
  1810.       case PAD_CHAR_DELETE_CHAR:
  1811.      if ((y = cmnum("PAD char delete char","",10,&z,xxstring)) < 0)
  1812.         return(y);
  1813.     if (z < 0 || z > 127) {
  1814.         printf("?The choices are 0 or 1 <= chardelete <= 127\n");
  1815.         return(-2);
  1816.     }
  1817.     if ((y = cmcfm()) < 0) return(y);
  1818.     break;
  1819.  
  1820.       case PAD_BUFFER_DELETE_CHAR:
  1821.      if ((y = cmnum("PAD buffer delete char","",10,&z,xxstring)) < 0)
  1822.         return(y);
  1823.     if (z < 0 || z > 127) {
  1824.         printf("?The choices are 0 or 1 <= bufferdelte <= 127\n");
  1825.         return(-2);
  1826.     }
  1827.     if ((y = cmcfm()) < 0) return(y);
  1828.     break;
  1829.  
  1830.       case PAD_BUFFER_DISPLAY_CHAR:
  1831.      if ((y = cmnum("PAD display line char","",10,&z,xxstring)) < 0)
  1832.         return(y);
  1833.     if (z < 0 || z > 127) {
  1834.         printf("?The choices are 0 or 1 <= displayline <= 127\n");
  1835.         return(-2);
  1836.     }
  1837.     if ((y = cmcfm()) < 0) return(y);
  1838.     break;
  1839.     }
  1840.     padparms[x] = z;
  1841.     return(success = 1);
  1842. }
  1843. #endif /* SUNX25 */ 
  1844.  
  1845. int
  1846. setat(rmsflg) int rmsflg; {
  1847.     int xx;
  1848.     if ((y = cmkey(attrtab,natr,"File Attribute packets","",xxstring)) < 0)
  1849.       return(y);    
  1850.     if (y == AT_XALL) {            /* ATTRIBUTES ALL ON or ALL OFF */
  1851.     if ((z = seton(&xx)) < 0) return(z);
  1852.     if (rmsflg) {
  1853.         printf("Sorry, command not available\n");
  1854.         return(-9);
  1855.     } else {
  1856.         atenci = xx;        /* Encoding in */
  1857.         atenco = xx;        /* Encoding out */
  1858.         atdati = xx;        /* Date in */
  1859.         atdato = xx;        /* Date out */
  1860.         atdisi = xx;        /* Disposition in/out */
  1861.         atdiso = xx;
  1862.         atleni = xx;        /* Length in/out (both kinds) */
  1863.         atleno = xx;
  1864.         atblki = xx;        /* Blocksize in/out */
  1865.         atblko = xx;
  1866.         attypi = xx;        /* File type in/out */
  1867.         attypo = xx;
  1868.         atsidi = xx;        /* System ID in/out */
  1869.         atsido = xx;
  1870.         atsysi = xx;        /* System-dependent params in/out */
  1871.         atsyso = xx;
  1872.     }
  1873.     return(z);
  1874.     } else if (y == AT_ALLY || y == AT_ALLN) { /* ATTRIBUTES ON or OFF */
  1875.     if ((x = cmcfm()) < 0) return(x);
  1876.     atcapr = (y == AT_ALLY) ? 1 : 0;
  1877.     if (rmsflg) {
  1878.         sstate = setgen('S', "132", atcapr ? "1" : "0", "");
  1879.         return((int) sstate);
  1880.     } else return(success = 1);
  1881.     }
  1882.     /* Otherwise, it's an individual attribute that wants turning off/on */
  1883.  
  1884.     if ((z = cmkey(onoff,2,"","",xxstring)) < 0) return(z);
  1885.     if ((x = cmcfm()) < 0) return(x);
  1886.  
  1887. /* There are better ways to do this... */
  1888. /* The real problem is that we're not separating the in and out cases */
  1889. /* and so we have to arbitrarily pick the "in" case, i.e tell the remote */
  1890. /* server to ignore incoming attributes of the specified type, rather */
  1891. /* than telling it not to send them.  The protocol does not (yet) define */
  1892. /* codes for "in-and-out-at-the-same-time". */
  1893.  
  1894.     switch(y) {
  1895.       case AT_DISP:
  1896.     if (rmsflg) {
  1897.         sstate = setgen('S', "142", z ? "1" : "0", "");
  1898.         return((int) sstate);
  1899.     }
  1900.     atdisi = atdiso = z; break;
  1901.       case AT_ENCO:
  1902.     if (rmsflg) {
  1903.         sstate = setgen('S', "141", z ? "1" : "0", "");
  1904.         return((int) sstate);
  1905.     }
  1906.     atenci = atenco = z; break;
  1907.       case AT_DATE:
  1908.     if (rmsflg) {
  1909.         sstate = setgen('S', "135", z ? "1" : "0", "");
  1910.         return((int) sstate);
  1911.     }
  1912.     atdati = atdato = z; break;
  1913.       case AT_LENB:
  1914.       case AT_LENK:
  1915.     if (rmsflg) {
  1916.         sstate = setgen('S', "133", z ? "1" : "0", "");
  1917.         return((int) sstate);
  1918.     }
  1919.     atleni = atleno = z; break;
  1920.       case AT_BLKS:
  1921.     if (rmsflg) {
  1922.         sstate = setgen('S', "139", z ? "1" : "0", "");
  1923.         return((int) sstate);
  1924.     }
  1925.     atblki = atblko = z; break;
  1926.       case AT_FTYP:
  1927.     if (rmsflg) {
  1928.         sstate = setgen('S', "134", z ? "1" : "0", "");
  1929.         return((int) sstate);
  1930.     }
  1931.     attypi = attypo = z; break;
  1932.       case AT_SYSI:
  1933.     if (rmsflg) {
  1934.         sstate = setgen('S', "145", z ? "1" : "0", "");
  1935.         return((int) sstate);
  1936.     }
  1937.     atsidi = atsido = z; break;
  1938.       case AT_SYSP:
  1939.     if (rmsflg) {
  1940.         sstate = setgen('S', "147", z ? "1" : "0", "");
  1941.         return((int) sstate);
  1942.     }
  1943.     atsysi = atsyso = z; break;
  1944.       default:
  1945.     printf("?Not available\n");
  1946.     return(-2);
  1947.     }
  1948.     return(1);
  1949. }
  1950.  
  1951. #ifndef NOSPL
  1952. int
  1953. setinp() {
  1954.     if ((y = cmkey(inptab,ninp,"","",xxstring)) < 0) return(y);
  1955.     switch (y) {
  1956.       case IN_DEF:            /* SET INPUT DEFAULT-TIMEOUT */
  1957.     z = cmnum("Positive number","",10,&x,xxstring);
  1958.     return(success = setnum(&indef,x,z,94));
  1959.       case IN_TIM:            /* SET INPUT TIMEOUT-ACTION */
  1960.     if ((z = cmkey(intimt,2,"","",xxstring)) < 0) return(z);
  1961.     if ((x = cmcfm()) < 0) return(x);
  1962.     intime[cmdlvl] = z;
  1963.     return(success = 1);
  1964.       case IN_CAS:            /* SET INPUT CASE */
  1965.     if ((z = cmkey(incast,2,"","",xxstring)) < 0) return(z);
  1966.     if ((x = cmcfm()) < 0) return(x);
  1967.     inpcas[cmdlvl] = z;
  1968.     return(success = 1);
  1969.       case IN_ECH:            /* SET INPUT ECHO */
  1970.     return(success = seton(&inecho));
  1971.       case IN_SIL:            /* SET INPUT SILENCE */
  1972.     z = cmnum("Seconds of inactivity before INPUT fails","",10,&x,
  1973.           xxstring);
  1974.     return(success = setnum(&insilence,x,z,-1));
  1975.     }
  1976.     return(0);
  1977. }
  1978. #endif /* NOSPL */
  1979.  
  1980. /*
  1981.   setlin -- parse name of and then open a communication device.
  1982.   Call with:
  1983.     xx == XXLINE for a serial (tty) line, XXHOST for a network host,
  1984.     zz == 0 means if user doesn't give a device name, continue current
  1985.             active connection (if any);
  1986.     zz != 0 means if user doesn't give a device name, then close the
  1987.             current connection and restore the default communication device.
  1988. */
  1989. int
  1990. setlin(xx, zz) int xx, zz; {
  1991.     if (xx == XYHOST) {            /* SET HOST <hostname> */
  1992. #ifndef NETCONN
  1993.         printf("?Network connections not supported\n");
  1994.     return(-9);
  1995. #else
  1996.     if (
  1997.         (nettype != NET_DEC) &&
  1998.         (nettype != NET_SX25) &&
  1999.             (nettype != NET_TCPB)) {
  2000.         printf("?Network type not supported\n");
  2001.         return(-9);
  2002.       }
  2003.     if (nettype != NET_TCPB) {    /* Not a TCP/IP connection */
  2004.                     /* Just get a text string */
  2005.         if ((x = cmtxt( zz ? 
  2006.    "Network host name,\n or carriage return to close an open connection" :
  2007.    "Network host name,\n or carriage return to resume an open connection",
  2008.                "",&s,xxstring)) < 0)
  2009.           return(x);
  2010.  
  2011.     } else {            /* TCP/IP connection... */
  2012.  
  2013.         /* Parse for host and service separately. */
  2014.  
  2015.         if ((x = cmfld( zz ?
  2016.    "IP host name or number,\n or carriage return to close an open connection" :
  2017.    "IP host name or number,\n or carriage return to resume an open connection",
  2018.                "",&s,xxstring)) < 0) {
  2019.         if (x != -3)        /* Parse error */
  2020.           return(x);        /* return it */
  2021.         else if (!zz)        /* No hostname given */
  2022.           return(1);        /* and none required, */
  2023.         }                /* continue current connection. */
  2024.         if (*s) {            /* If they gave a host name... */
  2025.         strcpy(line,s);        /* make a copy */
  2026.         /* Check for "host:service" */
  2027.         for ( ; (*s != '\0') && (*s != ':'); s++) ;
  2028.  
  2029.         /* If no service given, let them type one now. */
  2030.  
  2031.         if (!*s) {
  2032.             if ((x = cmfld(
  2033.     "TCP service name or number,\n or carriage return for telnet (23)",
  2034.                    "23",&s,xxstring)) < 0 && x != -3)
  2035.               return(x);
  2036.             if (*s) {        /* If they gave a service, */
  2037.             strcat(line,":"); /* concatenate it to the hostname */
  2038.             strcat(line,s);    /* separated by a colon, because */
  2039.             }            /* this is how ttopen() wants it. */
  2040.         }
  2041.         if ((x = cmcfm()) < 0) return(x); /* Confirm the command */
  2042.         s = line;
  2043.         }
  2044.     }
  2045.  
  2046.     /* New connection wanted. */
  2047.  
  2048.     ttflui();            /* Clear away buffered up junk */
  2049.     ttclos(0);            /* Close old connection, if any */
  2050.     if (oldplex > -1)        /* Restore duplex setting. */
  2051.       duplex = oldplex;
  2052.     if (*s) {            /* They gave a hostname */
  2053.         x = 1;            /* Network connection always local */
  2054.         mdmsav = mdmtyp;        /* Remember old modem type */
  2055.         mdmtyp = -nettype;        /* Special code for network */
  2056.         if (nettype == NET_TCPB) {    /* For TCP/IP telnet connections */
  2057.         oldplex = duplex;    /* Remember previous duplex */
  2058.         duplex = 0;        /* Set full duplex and let */
  2059.                                 /* negotiations change if necessary. */
  2060.         }
  2061.     } else {            /* They just said "set host" */
  2062.         if (network && msgflg)
  2063.           printf(" Closing connection\n");
  2064.         s = dftty;            /* So go back to normal */
  2065.         x = dfloc;            /* default tty, location, */
  2066.         network = 0;        /* No more network connection. */
  2067.         duplex = oldplex;        /* Restore old duplex setting. */
  2068.         if (mdmtyp < 0) {        /* Switching from net to async? */
  2069.         if (mdmsav > -1)    /* Restore modem type from last */
  2070.           mdmtyp = mdmsav;    /* SET MODEM command, if any. */
  2071.         else
  2072.           mdmtyp = 0;
  2073.         }
  2074.     }
  2075. #endif /* NETCONN */
  2076.     }
  2077.  
  2078. /* Serial tty device, possibly modem, connection... */
  2079.  
  2080.     if (xx == XYLINE) {            /* SET LINE */
  2081. #ifdef OS2                /* or SET PORT */
  2082. /*
  2083.   User can type:
  2084.     COM1..COM8 = Regular COM port
  2085.     1..8       = Synonym for COM1..COM8, is translated to COM1..COM8
  2086.     _n         = (n is a number) = open file handle
  2087.     string     = any text string = name of some other kind of device,
  2088.                  taken literally, as given.
  2089. */
  2090.     if ((x = cmtxt("Communication device name",dftty,&s,xxstring)) < 0)
  2091.       return(x);
  2092.     debug(F110,"OS2 SET PORT s",s,0);
  2093.     y = lookup(os2devtab,s,nos2dev,&x); /* Look up in keyword table */
  2094.     debug(F101,"OS2 SET PORT x","",x);
  2095.     debug(F101,"OS2 SET PORT y","",y);
  2096.     if ((y > -1) && (x >= 0 && x < 8)) { /* User typed a digit 1..8 */
  2097.         s = os2devtab[x+8].kwd;    /* Substitite its real name */
  2098.         debug(F110,"OS2 SET PORT subst s",s,"");
  2099.     } else if (*s == '_') {        /* User used "_" prefix */
  2100.         s++;            /* Remove it */
  2101.         debug(F110,"OS2 SET PORT _subst s",s,0); /* Rest must be numeric */
  2102.         if (!rdigits(s)) {
  2103.         printf("?Invalid format for file handle\n");
  2104.         return(-9);
  2105.         }
  2106.     }
  2107.     debug(F110,"OS2 SET PORT final s",s,"");
  2108. #else
  2109.     if ((x = cmtxt("Communication device name",dftty,&s,xxstring)) < 0)
  2110.       return(x);
  2111. #endif /* OS2 */
  2112.  
  2113.     if (local) ttflui();        /* Clear away buffered up junk */
  2114.     ttclos(0);            /* Close old line, if any was open */
  2115.     if (*s) {            /* They gave a device name */
  2116.         x = -1;            /* Let ttopen decide about it */
  2117.     } else {            /* They just said "set line" */
  2118.         s = dftty;            /* so go back to normal tty */
  2119.         x = dfloc;            /* and mode. */
  2120.     }
  2121.     if (mdmtyp < 0) {        /* Switching from net to async? */
  2122.         if (mdmsav > -1)        /* Restore modem type from last */
  2123.           mdmtyp = mdmsav;        /* SET MODEM command, if any. */
  2124.         else
  2125.           mdmtyp = 0;
  2126.         mdmsav = -1;
  2127.     }
  2128.     if (oldplex > -1) {        /* Restore previous duplex setting. */
  2129.         duplex = oldplex;
  2130.         oldplex = -1;
  2131.     }
  2132.     network = 0;            /* No more network. */
  2133.     }
  2134. #ifdef COMMENT
  2135. /*
  2136.   The following is removed, not so much because it's a horrible hack, but
  2137.   because it only works if the SET FLOW command was given *before* the SET
  2138.   LINE command, whereas normally these commands can be given in any order.
  2139. */
  2140. #ifdef NEXT
  2141. /*
  2142.   This is a horrible hack, but it's nice for users.  On the NeXT, you select
  2143.   RTS/CTS hardware flow control not by system calls, but by referring to the
  2144.   device with a different name.  If the user has asked for RTS/CTS flow
  2145.   control on a NeXT, but used the non-RTS/CTS device name in the SET LINE
  2146.   command, we make the appropriate substitute here.  I wonder how much bigger
  2147.   this section of code will grow as the years go by... 
  2148. */
  2149.     if ((flow == FLO_RTSC) &&        /* RTS/CTS flow control selected */
  2150.     strcmp(s,dftty)) {        /*  ...on external port? */
  2151.     y = strlen(s);            /* Yes, insert "f" as next-to-last */
  2152.     if (s[y-2] != 'f') {        /* character in device name if not */
  2153.         strcpy(line,s);        /* already there... */
  2154.         line[y] = line[y-1];    /* So /dev/cua => /dev/cufa, etc. */
  2155.         line[y-1] = 'f';
  2156.         line[y+1] = '\0';
  2157.         s = line;
  2158.     }
  2159.     }
  2160. #endif /* NEXT */
  2161. #endif /* COMMENT */
  2162.  
  2163.     if ((y = ttopen(s,&x,mdmtyp,cdtimo)) < 0 ) { /* Open the new line */
  2164.     if (y == -2) {
  2165.         printf("?Timed out, no carrier.\n");
  2166.         printf("Try SET CARRIER OFF and SET LINE again, or else\n");
  2167.         printf("SET MODEM, SET LINE, and then DIAL.\n");
  2168.     } else if (y == -3) {
  2169.         printf("Sorry, access to lock denied: %s\n",s);
  2170.     } else if (y == -4) {
  2171.         printf("Sorry, access to device denied: %s\n",s);
  2172.     } else if (y == -5) {
  2173. #ifdef VMS
  2174.         printf("Sorry, device is in use or otherwise unavailable: %s\n",s);
  2175. #else
  2176.         printf("Sorry, device is in use: %s\n",s);
  2177. #endif /* VMS */
  2178.         } else {            /* Other error. */
  2179. #ifndef VMS
  2180.         if (errno) {
  2181.         int x;            /* Find a safe, long buffer */
  2182.         x = strlen(line) + 2;    /* for the error message. */
  2183.         if (LINBUFSIZ - x > 100) { /* Allow room for 100 chars */
  2184.             tp = line + x;
  2185.             sprintf(tp,"Sorry, can't open connection: %s",s);
  2186.             perror(tp);
  2187.         } else printf("Sorry, can't open connection: %s\n",s);
  2188.         } else
  2189. #endif /* VMS */
  2190.           printf("Sorry, can't open connection: %s\n",s);
  2191.     }    
  2192.     local = dfloc;            /* Go back to normal */
  2193. #ifndef MAC
  2194.     strcpy(ttname,dftty);        /* Restore default tty name */
  2195. #endif /* MAC */
  2196.     speed = ttgspd();
  2197.     network = 0;            /* No network connection active */
  2198.     return(success = 0);        /* Return failure */
  2199.     }
  2200.     if (x > -1) local = x;        /* Opened ok, set local/remote. */
  2201.     network = (mdmtyp < 0);        /* Remember connection type. */
  2202. #ifdef TNCODE
  2203.     if (network) tn_init = 0;        /* Say telnet not init'd yet. */
  2204. #endif /* TNCODE */
  2205.     strcpy(ttname,s);            /* Copy name into real place. */
  2206.     speed = ttgspd();            /* Get the current speed. */
  2207.     debug(F111,"set line ",ttname,local);
  2208. #ifdef NETCONN
  2209. #ifdef SUNX25
  2210.     if (nettype == NET_SX25) duplex = 1; /* Duplex half */
  2211. #endif /* SUNX25 */
  2212. #endif /* NETCONN */
  2213.     return(success = 1);
  2214. }
  2215. #endif /* NOICP */
  2216.